home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / lz13.zip / LZDCMP2.ASM < prev    next >
Assembly Source File  |  1993-05-01  |  6KB  |  249 lines

  1.     title    lzdcmp - file decompressor using limpel-ziev algorithm
  2.  
  3. ;Tom Pfau
  4. ;Digital Equipment Corporation
  5. ;Parsippany, NJ
  6. ;
  7. ;v1.2 - Toad Hall Tweak
  8. ; - converting to .COM file
  9. ; - uses tweaked MACROS2.MLB
  10.  
  11. ;Constants
  12. CLEAR        equ    256
  13. EOF        equ    257
  14. FIRST_FREE    equ    258
  15. ;MAXMAX        equ    4096
  16.  
  17.     include    macros2.mlb
  18.  
  19. ;Hash table entry
  20. hash_rec    struc
  21. next    dw    ?            ; prefix code
  22. char    db    ?            ; suffix char
  23. hash_rec    ends
  24.  
  25. ;Start coding
  26. code    segment para public 'code'
  27.     assume    CS:code,DS:code, ES:code    ;TH
  28.     org    100H            ;TH
  29.  
  30. LzDcmp2    proc    near
  31.     jmp    Start            ;TH
  32.  
  33. input_prompt    db    'Input file: $'
  34. output_prompt    db    'Output file: $'
  35. input_file    db    80,0,80 dup (?)
  36. output_file    db    80,0,80 dup (?)
  37. crlf        db    13,10,'$'
  38. input_handle    dw    ?
  39. output_handle    dw    ?
  40. cur_code    dw    ?
  41. old_code    dw    ?
  42. in_code        dw    ?
  43. free_code    dw    FIRST_FREE
  44. stack_count    dw    0
  45. nbits        dw    9
  46. max_code    dw    512
  47. fin_char    db    ?
  48. k        db    ?
  49. masks        dw    1ffh,3ffh,7ffh,0fffh
  50. bit_offset    dw    0
  51. output_offset    dw    0
  52. LzDcmp2    endp
  53.  
  54.  
  55. start    proc    near
  56.     print    input_prompt        ;Get file names
  57.     input    input_file
  58.     print    crlf
  59.     print    output_prompt
  60.     input    output_file
  61.     print    crlf
  62.     mov    al,input_file+1        ;Terminate with nulls
  63.     xor    ah,ah
  64.     mov    si,ax
  65.     mov    input_file+2[si],ah    ;TH 0
  66.     mov    al,output_file+1
  67.     mov    si,ax
  68.     mov    output_file+2[si],ah    ;TH 0
  69.     hopen    input_file+2,0        ;Open input and output
  70.     mov    input_handle,ax
  71.     hcreat    output_file+2,0
  72.     mov    output_handle,ax
  73.     call    decompress        ;Decompress files
  74.     hclose    input_handle
  75.     hclose    output_handle
  76.     exit                ;Done
  77. start    endp
  78.  
  79. decompress    proc    near
  80.     hread    input_handle,input_buffer,1024    ;Read from input
  81.  
  82. l1:    call    read_code        ;Get a code
  83.     cmp    ax,EOF            ;End of file?
  84.     jne    l2            ;no
  85.  
  86.     cmp    output_offset,0        ;Data in output buffer?
  87.     je    l1a            ;no
  88.      hwrite    output_handle,output_buffer,output_offset    ;Flush buffer
  89. l1a:    ret                ;done
  90.  
  91. l2:    cmp    ax,CLEAR        ;Clear code?
  92.     jne    l7            ;no
  93.  
  94.     call    init_tab        ;Initialize table
  95.     call    read_code        ;Read next code
  96.     mov    cur_code,ax        ;Initialize variables
  97.     mov    old_code,ax
  98.     mov    k,al
  99.     mov    fin_char,al
  100.     call    write_char        ;Write character
  101.     jmp    l1            ;Get next code
  102.  
  103. l7:    mov    cur_code,ax        ;Save new code
  104.     mov    in_code,ax
  105.     cmp    ax,free_code        ;Code in table? (k<w>k<w>k)
  106.     jl    l11            ;yes
  107.      mov    ax,old_code        ;get previous code
  108.      mov    cur_code,ax        ;make current
  109.      mov    al,fin_char        ;get old last char
  110.      push    ax            ;push it
  111.      inc    stack_count
  112.      mov    ax,cur_code        ;TH sigh ...
  113. l11:
  114. ;TH AX should have cur_code in any case
  115. ;    cmp    cur_code,255        ;Code or character?
  116.     cmp    ax,255            ;TH Code or character?
  117.     jle    l15            ;Char
  118.  
  119. ;     mov    bx,cur_code        ;Convert code to address
  120.      mov    bx,ax            ;TH Convert code to address
  121.      call    index
  122.      mov    al,2[bx]        ;Get suffix char
  123.      push    ax            ;push it
  124.      inc    stack_count
  125.      mov    ax,[bx]            ;Get prefix code
  126.      mov    cur_code,ax        ;Save it
  127.      jmp    l11            ;Translate again
  128.  
  129. l15:
  130. ;TH ax should still have cur_code
  131. ;    mov    ax,cur_code        ;Get code
  132.     mov    fin_char,al        ;Save as final, k
  133.     mov    k,al
  134.     push    ax            ;Push it
  135.     inc    stack_count
  136.     mov    cx,stack_count        ;Pop stack
  137.     jcxz    l18            ;If anything there
  138. l17:     pop    ax
  139.      call    write_char
  140.      loop    l17
  141. l18:    mov    stack_count,cx        ;Clear count on stack
  142.     call    add_code        ;Add new code to table
  143.     mov    ax,in_code        ;Save input code
  144.     mov    old_code,ax
  145.     mov    bx,free_code        ;Hit table limit?
  146.     cmp    bx,max_code
  147.     jl    l23            ;Less means no
  148.      cmp    nbits,12        ;Still within twelve bits?
  149.      je    l23            ;no (next code should be clear)
  150.       inc    nbits            ;Increase code size
  151.       shl    max_code,1        ;Double max code
  152. l23:    jmp    l1            ;Get next code
  153. decompress    endp    
  154.  
  155. read_code    proc    near
  156.     mov    ax,bit_offset        ;Get bit offset
  157.     add    ax,nbits        ;Adjust by code size
  158.     xchg    bit_offset,ax        ;Swap
  159.     mov    cx,8            ;Calculate byte offset
  160.     xor    dx,dx
  161.     div    cx
  162.     cmp    ax,1021            ;Approaching end of buffer?
  163.     jl    rd0            ;no
  164.  
  165.     push    dx            ;Save offset in byte
  166.     add    dx,nbits        ;Calculate new bit offset
  167.     mov    bit_offset,dx
  168.     mov    cx,1024            ;1k buffer
  169.     mov    bp,ax            ;save byte offset
  170.     sub    cx,ax            ;Calculate bytes left
  171.     mov    di,offset input_buffer    ;TH Point to beginning of buffer
  172.     add    ax,di            ;TH Point to char
  173.  
  174.     mov    si,ax
  175. rep    movsb                ;Move last chars down
  176.     hread    input_handle,[di],bp    ;Fill rest of buffer
  177.     xor    ax,ax            ;Clear ax
  178.     pop    dx            ;Restore offset in byte
  179. rd0:    add    ax,offset input_buffer    ;Point to char
  180.     mov    si,ax
  181.     lodsw                ;Get word
  182.     mov    bx,ax            ;Save in AX
  183.     lodsb                ;Next byte
  184.     mov    cx,dx            ;Offset in byte
  185.     jcxz    rd2            ;If zero, skip shifts
  186. rd1:     shr    al,1            ;Put code in low (code size) bits of BX
  187.      rcr    bx,1
  188.      loop    rd1
  189. rd2:    mov    ax,bx            ;put code in ax
  190.     mov    bx,nbits        ;mask off unwanted bits
  191.     sub    bx,9
  192.     shl    bx,1
  193.     and    ax,masks[bx]
  194.     ret
  195. read_code    endp
  196.  
  197. init_tab    proc    near
  198.     mov    nbits,9            ;Initialize variables
  199.     mov    max_code,512
  200.     mov    free_code,FIRST_FREE
  201.     ret
  202. init_tab    endp
  203.  
  204. write_char    proc    near
  205.     mov    di,output_offset    ;Get offset in buffer
  206.     cmp    di,1024            ;Full?
  207.     jl    wc1            ;no
  208.      push    ax            ;Save registers
  209.      push    cx
  210.      hwrite    output_handle,output_buffer,di    ;Write buffer to file
  211.      pop    cx
  212.      pop    ax
  213.      xor    di,di    ;TH        ;Point to beginning of buffer
  214.      mov    output_offset,di
  215. wc1:
  216. ;    lea    di,output_buffer[di]    ;Point into buffer
  217.     add    di,offset output_buffer    ;TH
  218.     stosb                ;Store char
  219.     inc    output_offset        ;Increment number of chars in buffer
  220.     ret
  221. write_char    endp
  222.  
  223. index        proc    near
  224.     mov    bp,bx            ;bx = bx * 3 (3 byte entries)
  225.     shl    bx,1            ;bp = bx
  226.     add    bx,bp            ;bx = bx * 2 + bp
  227.     add    bx,offset hash        ;TH add in hashtable base offset
  228.     ret
  229. index        endp
  230.  
  231. add_code    proc    near
  232.     mov    bx,free_code        ;Get new code
  233.     call    index            ;convert to address
  234.     mov    al,k            ;get suffix char
  235.     mov    [bx].char,al        ;save it
  236.     mov    ax,old_code        ;get prefix code
  237.     mov    [bx].next,ax        ;save it
  238.     inc    free_code        ;set next code
  239.     ret
  240. add_code    endp
  241.  
  242. input_buffer    equ    $            ;db    1024 dup (?)
  243. output_buffer    equ    input_buffer+1024    ;db    1024 dup (?)
  244. hash        equ    output_buffer+1024
  245.  
  246. code    ends
  247.  
  248.     end    LzDcmp2
  249.